From 4259aba8839ab8f3688284a25265868a3d8f3352 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Thu, 12 Jan 2017 18:08:32 +0100 Subject: [PATCH] wayland: avoid 0 width/height anchor rectangle Passing a rectangle with zero width or height to xdg_shell-v6 set_anchor_rect() will cause a protocol error and terminate the client, as with gedit when pressing the Win key. Reason for this is because the rectangle used to set the anchor comes from gtk_text_layout_get_iter_location() which uses the pango layout width/height, which can be empty if there is not character at the given location. Make sure we don't use 0 as width or height as an anchor rectangle to avoid the protocol error, and compensate the logical position of the given rectangle if the size is changed, so that the actual position remains as expected by the client. https://bugzilla.gnome.org/show_bug.cgi?id=777176 --- gdk/wayland/gdkwindow-wayland.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 466f7c3c72..2348d4123a 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -2635,6 +2635,34 @@ gdk_window_wayland_move_resize (GdkWindow *window, gdk_wayland_window_maybe_configure (window, width, height, impl->scale); } +/* Avoid zero width/height as this is a protocol error */ +static void +sanitize_anchor_rect (GdkWindow *window, + GdkRectangle *rect) +{ + gint original_width = rect->width; + gint original_height = rect->height; + GdkWindow *parent = get_popup_parent (window); + + rect->width = MAX (1, rect->width); + rect->height = MAX (1, rect->height); + rect->x -= rect->width - original_width; + rect->y -= rect->height - original_height; + + /* Make sure the anchor rectangle does not extend outside the window + * geometry of the parent surface. + */ + if (parent) + { + GdkRectangle geometry; + + /* The rectangle is relative to the parent window geometry */ + gdk_wayland_window_get_window_geometry (parent, &geometry); + rect->x = CLAMP (rect->x, 0, geometry.width); + rect->y = CLAMP (rect->y, 0, geometry.height); + } +} + static void gdk_window_wayland_move_to_rect (GdkWindow *window, const GdkRectangle *rect, @@ -2647,6 +2675,8 @@ gdk_window_wayland_move_to_rect (GdkWindow *window, GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); impl->pending_move_to_rect.rect = *rect; + sanitize_anchor_rect (window, &impl->pending_move_to_rect.rect); + impl->pending_move_to_rect.rect_anchor = rect_anchor; impl->pending_move_to_rect.window_anchor = window_anchor; impl->pending_move_to_rect.anchor_hints = anchor_hints; -- 2.30.2